﻿using System;
using System.CodeDom.Compiler;
using System.Collections.Generic;
using System.Data;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Reflection.Emit;
using System.Text;
using Framework.Common;
using Framework.Common.Attributes;
using Framework.Common.Reflection;
using Framework.Common.Reflection.RunSharpEmit;
using Microsoft.CSharp;

namespace Framework.Sample
{
    [OrderedDesc("7)    CodeDom sample")]
    class Test7 : ITest
    {
        public void Run()
        {
            Console.WriteLine(@"CodeDom sample");
            Type instanceType = typeof(int);
            Console.WriteLine(instanceType.Name);
            string code = @"

using System;
using System.Collections.Generic;
using System.Text;
using System.Reflection;

namespace Framework.Sample
{
    public class CodeTest
    {
        public static void Main()
        {
            Type instanceType = typeof(int);
            Console.WriteLine(instanceType.Name);
            Console.WriteLine(""asfasfasdf"");
        }
    }
}";

            Console.WriteLine(code);
            Console.ReadLine();

            // 2. 设置编译参数，主要是指定将要引用哪些程序集
            CompilerParameters cp = new CompilerParameters();
            cp.GenerateExecutable = false;
            cp.GenerateInMemory = true;
            cp.ReferencedAssemblies.Add("System.dll");

            // 3. 获取编译器并编译代码
            // 获取与CLR匹配版本的C#编译器可以这样写：CodeDomProvider.CreateProvider("CSharp")

            Dictionary<string, string> dict = new Dictionary<string, string>();
            dict["CompilerVersion"] = "v4.0";
            dict["WarnAsError"] = "false";

            CSharpCodeProvider csProvider = new CSharpCodeProvider(dict);
            CompilerResults cr = csProvider.CompileAssemblyFromSource(cp, code);

            // 4. 检查有没有编译错误
            if (cr.Errors != null && cr.Errors.HasErrors)
            {
                foreach (CompilerError error in cr.Errors)
                    Console.WriteLine(error.ErrorText);

                return;
            }

            // 5. 获取编译结果，它是编译后的程序集
            Assembly asm = cr.CompiledAssembly;

            Type t = asm.GetType("Framework.Sample.CodeTest");
            MethodInfo method = t.GetMethod("Main");
            method.Invoke(null, null);
        }

    }
}
